
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 加载Iris数据集，选择Setosa和Versicolor
data = load_iris()
X = data.data[:100]  # 只选择Setosa和Versicolor
y = data.target[:100]

# 数据标准化
scaler = StandardScaler()
X = scaler.fit_transform(X)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 构建弱分类器函数
def weak_classifier(X, feature_index, threshold):
    # 确保X是二维数组
    if X.ndim == 1:
        X = X.reshape(1, -1)  # 将一维数组转为二维
    return np.where(X[:, feature_index] >= threshold, 1, -1)

# 选择M个弱分类器
M = 10  # 假设构建10个弱分类器
classifiers = []
accuracies = []

# 构造多个弱分类器
for i in range(M):
    feature_index = i % 4  # 随机选择特征
    threshold = np.random.uniform(np.min(X_train[:, feature_index]), 
                                 np.max(X_train[:, feature_index]))  # 随机设定阈值
    classifiers.append((feature_index, threshold))  # 存储每个弱分类器的特征索引和阈值
    
    # 计算每个弱分类器的准确率
    predictions = weak_classifier(X_train, feature_index, threshold)
    accuracy = np.sum(predictions == y_train) / len(y_train)
    accuracies.append(accuracy)

# 输出每个弱分类器的准确率
for j, acc in enumerate(accuracies):
    print(f"弱分类器{j+1}准确率: {acc:.4f}")

# QUBO目标函数定义
def QUBO_model(w, X_train, y_train, classifiers, lambda_reg=0.1):
    error = 0
    for i in range(len(X_train)):
        prediction = np.sum(
            [w[j] * weak_classifier(X_train[i], classifiers[j][0], classifiers[j][1]) 
             for j in range(len(classifiers))])
        error += (prediction - y_train[i]) ** 2
    
    regularization = lambda_reg * np.sum(w)
    return error + regularization

# 模拟退火算法框架
def simulated_annealing(Q, max_iter=1000, T_start=100, T_end=1e-3):
    w = np.random.choice([0, 1], size=len(classifiers))  # 初始解
    T = T_start
    best_w = w.copy()
    best_energy = Q(w)
    
    for t in range(max_iter):
        new_w = w.copy()
        # 随机扰动
        flip_index = np.random.randint(0, len(w))
        new_w[flip_index] = 1 - new_w[flip_index]
        
        energy = Q(new_w)
        if energy < best_energy or np.random.rand() < np.exp((best_energy - energy) / T):
            w = new_w
            best_energy = energy
        T = max(T_end, T * 0.99)  # 降温
    
    return best_w

# 添加评估模型函数
def evaluate_model(X_test, y_test, weights, classifiers):
    predictions = []
    for i in range(len(X_test)):
        # 计算加权预测
        pred = np.sum([weights[j] * weak_classifier(X_test[i], classifiers[j][0], classifiers[j][1]) 
                      for j in range(len(classifiers))])
        # 二分类问题，大于0为正类，小于等于0为负类
        predictions.append(1 if pred > 0 else 0)
    
    # 计算准确率
    accuracy = np.sum(predictions == y_test) / len(y_test)
    return accuracy

# 求解最优分类器组合
best_weights = simulated_annealing(lambda w: QUBO_model(w, X_train, y_train, classifiers), max_iter=1000)

# 评估模型
# 在测试集上面评估模型准确率
accuracy = evaluate_model(X_test, y_test, best_weights, classifiers)
print(f"模型的准确率为: {accuracy:.4f}")